package com.hd.controller.login;

import com.alibaba.fastjson.JSONObject;
import com.hd.commons.shiro.filter.ForceLogoutFilter;
import com.hd.controller.base.BaseController;
import com.hd.entity.enums.PushMsgTypeEnum;
import com.hd.entity.netty.PushMsg;
import com.hd.netty.constant.Constant;
import com.hd.netty.server.WebSocketServerHandler;
import com.hd.util.DateUtil;
import com.hd.util.JsonUtil;
import io.netty.channel.ChannelHandlerContext;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

import static org.apache.shiro.subject.support.DefaultSubjectContext.PRINCIPALS_SESSION_KEY;

/**
 * hzhh123 2019/5/9 18:01
 * shiro的session管理
 */
@Controller
@RequestMapping("/sessionManager")
public class SeesionManagerController extends BaseController {

    @Autowired
    private SessionDAO sessionDAO;
    @Autowired
    private WebSocketServerHandler webSocketServerHandler;

//    @Autowired
//    private RedisSessionDAO redisSessionDAO;

    @RequestMapping("/index")
    public String index(){
        return "jsp/sys/user/online";
    }

    /**
     * 在线用户管理
     * @return
     */
    @ResponseBody
    @RequestMapping("/getSessions")
    public Object getSessions() {
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        return getSessionsMap(sessions);
    }

    /**
     * 踢出用户
     * @param sessionId
     * @return
     */
    @RequiresRoles(value = {"ROLE_ADMIN"})
    @ResponseBody
    @RequestMapping("/kickout")
    public Object kickout(String sessionId) {
        if(SecurityUtils.getSubject().getSession().getId().equals(sessionId)){
            return renderError("不能踢除当前用户自身");
        }
        Session session = sessionDAO.readSession(sessionId);
        if (session != null) {
            if (session != null) {
                session.setAttribute(ForceLogoutFilter.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);
                //netty推送消息至web端
                ChannelHandlerContext ctx = Constant.pushCtxMap.get(sessionId);
                if (ctx != null) {
                    PushMsg pushMsg=new PushMsg();
                    pushMsg.setCreateTime(new Date());
                    pushMsg.setId(UUID.randomUUID().toString());
                    pushMsg.setMsg("你已经被管理员踢除,请重新登陆");
                    pushMsg.setType(PushMsgTypeEnum.KICKOUT.getType());
                    pushMsg.setUrl("/login?forceLogout=1");
                    WebSocketServerHandler.push(ctx, JsonUtil.toJson(pushMsg));
                    sessionDAO.delete(session);
                }
            }
        }
        return renderSuccess("踢除用户成功");
    }

    /**
     * 踢出用户
     * @param
     * @return
     */
//    @RequiresRoles(value = {"ROLE_ADMIN"})
//    @ResponseBody
//    @RequestMapping("/kickout2")
//    public Object kickout2(String sessionId) {
//        if(SecurityUtils.getSubject().getSession().getId().equals(sessionId)){
//            return renderError("不能踢除当前用户自身");
//        }
//        Session session = redisSessionDAO.readSession(sessionId);
//        if (session != null) {
//            if (session != null) {
//                session.setAttribute(ForceLogoutFilter.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);
//                //netty推送消息至web端
//                ChannelHandlerContext ctx = Constant.pushCtxMap.get(sessionId);
//                if (ctx != null) {
//                    PushMsg pushMsg=new PushMsg();
//                    pushMsg.setCreateTime(new Date());
//                    pushMsg.setId(UUID.randomUUID().toString());
//                    pushMsg.setMsg("你已经被管理员踢除,请重新登陆");
//                    pushMsg.setType(PushMsgTypeEnum.KICKOUT.getType());
//                    pushMsg.setUrl("/login?forceLogout=1");
//                    WebSocketServerHandler.push(ctx, JsonUtil.toJson(pushMsg));
//                    redisSessionDAO.delete(session);
//                }
//            }
//        }
//        return renderSuccess("踢除用户成功");
//    }
//

    @RequestMapping("/toNetty")
    public String toNetty(Model model) {
        model.addAttribute("sessionId", SecurityUtils.getSubject().getSession().getId());
        return "jsp/netty/test1";
    }


    /**
     * redis作缓存，读取session
     * @return
     */
//    @RequestMapping("getRedisSessions")
//    @ResponseBody
//    public Object getRedisSessions(){
//        Collection<Session> activeSessions = redisSessionDAO.getActiveSessions();
//        return getSessionsMap(activeSessions);
//    }

    private Object getSessionsMap(Collection<Session> activeSessions) {
        List<Map<String, Object>> sessionListMap = new ArrayList<Map<String, Object>>();
        Iterator<Session> it = activeSessions.iterator();
        while (it.hasNext()) {
            Session session = it.next();
            if (session.getAttribute(PRINCIPALS_SESSION_KEY) != null) {
                System.out.println("*******************************在线用户***************************************");
                String json= JsonUtil.toJson(session.getAttribute(PRINCIPALS_SESSION_KEY));
                System.out.println(json);
                JSONObject inJson = JSONObject.parseObject(json);
                JSONObject outJson=JSONObject.parseObject(inJson.getString("primaryPrincipal"));
                System.out.println("******************************************************************************");
                Map<String, Object> resultMap = new HashMap<String, Object>();
                resultMap.put("sessionId", session.getId());
                resultMap.put("startTime", DateUtil.datetimeToStr(session.getStartTimestamp()));
                resultMap.put("host", session.getHost());
                resultMap.put("lastAccessTime", DateUtil.datetimeToStr(session.getLastAccessTime()));
                resultMap.put("timeout", session.getTimeout());
                resultMap.put("username",outJson.getString("username"));
                resultMap.put("name",outJson.getString("name"));
                sessionListMap.add(resultMap);
            }
        }
        return sessionListMap;
    }

}
